package com.traveldream.entity_managers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.traveldream.entities.CustomPacket;
import com.traveldream.entities.Flight;
import com.traveldream.entities.User;
import com.traveldream.entities.DefaultPacket;
import com.traveldream.entities.Packet;
import com.traveldream.entities.Place;
import com.traveldream.entities.Product;

/**
 * Session Bean implementation class PacketManagerBean
 * 
 */
@Stateless
public class PacketManagerBean implements PacketManager {

	// bisogna indicare che si usa la persistenza configurata nel package Common
	@PersistenceContext(unitName="TravelDreamCommon")
	EntityManager em;
	    
   	@Override
	public List<DefaultPacket> findAllDefaultPackets() {
   		Query query = em.createNamedQuery("DefaultPacket.findAll",DefaultPacket.class);
		List<DefaultPacket> results=new ArrayList<DefaultPacket>();
   		for( Object o : query.getResultList() ) 
   			results.add((DefaultPacket)o);
		return results;
	}
   	
	@Override
	public List<CustomPacket> findByCustomer(User c) {
		// filter on packet-creator
		Query query = em.createNamedQuery("CustomPacket.findByUser",CustomPacket.class).setParameter("UserEmail", c.getEmail());
		List<CustomPacket> results=new ArrayList<CustomPacket>();
   		for( Object o : query.getResultList() ) 
   			results.add((CustomPacket)o);
		return results;
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<DefaultPacket> findByDates(Date start, Date end) {
		List<DefaultPacket> results=new ArrayList<DefaultPacket>();
		if( start!=null && end!=null ) {
			start.setDate(start.getDate()+1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Packet.findBeetwenDates",Packet.class).setParameter("start",start).setParameter("end", end);
			for( Object o : query.getResultList() ) {
				Packet pp=(Packet)o;
				results.add(this.findDefaultPacket(pp.getId()));
			}
		}
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Packet.findByEndingDate",Packet.class).setParameter("end", end);
			for( Object o : query.getResultList() ) {
				Packet pp=(Packet)o;
				results.add(this.findDefaultPacket(pp.getId()));
			}
		} else { //end==null
			start.setDate(start.getDate()+1);
			Query query = em.createNamedQuery("Packet.findByStartingDate",Packet.class).setParameter("start", start);
			for( Object o : query.getResultList() ) {
				Packet pp=(Packet)o;
				results.add(this.findDefaultPacket(pp.getId()));
			}
		}
		return results;
	}

	@Override
	public List<DefaultPacket> findByPlace(Place p) {
		Query query = em.createNamedQuery("CustomPacket.findByPlace",CustomPacket.class).setParameter("placeName", p.getName());
		List<DefaultPacket> results=new ArrayList<DefaultPacket>();
   		for( Object o : query.getResultList() ) 
   			results.add((DefaultPacket)o);
		return results;
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<DefaultPacket> findByDatesAndPlace(Date start, Date end,Place place) {
		List<DefaultPacket> results=new ArrayList<DefaultPacket>();
		if( start!=null && end!=null ) {
			System.out.print("FIND PACKAGES between "+start.toString()+" and "+end.toString()+" at "+place.getName());
			start.setDate(start.getDate()-1);
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("DefaultPacket.findBetweenDatesByPlace",Flight.class)
							.setParameter("start",start)
							.setParameter("end", end)
							.setParameter("placeNamee",place.getName());
			System.out.print(query.toString());
			for( Object o : query.getResultList() ) 
				results.add((DefaultPacket)o);
		}
		/* non mi servono
		else if ( start==null ) {
			end.setDate(end.getDate()+1);
			Query query = em.createNamedQuery("Flight.findByEndingDate",Flight.class).setParameter("end", end); 
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		} else { //end==null
			start.setDate(start.getDate()-1);
			Query query = em.createNamedQuery("Flight.findByStartingDate",Flight.class).setParameter("start", start);
			for( Object o : query.getResultList() ) 
				results.add((Flight)o);
		}
		*/
		return results;
	}
	
	@Override
	public DefaultPacket create(DefaultPacket dp) {
		// persist & flush em
        this.create(dp.getPacket());
        em.persist(dp);
        em.flush();
        em.refresh(dp);
        // return persisted object
        return dp;	
	}

	@Override
	public CustomPacket create(CustomPacket cp) {
		// persist & flush em
		this.create(cp.getPacket());
        em.persist(cp);
        em.flush();
        em.refresh(cp);
        // return persisted object
        return cp;	
	}
	
	@Override
	public Packet create(Packet p){
		
		em.persist(p);
		em.flush();
		return p;
	}

	@Override
	public DefaultPacket update(DefaultPacket dp) {
		this.update(dp.getPacket());
		em.merge(dp);
		em.flush();
		return dp;
	}

	@Override
	public CustomPacket update(CustomPacket cp) {
		this.update(cp.getPacket());
		em.merge(cp);
		em.flush();
		return cp;
	}
	
	@Override
	public Packet update(Packet p) {
		for(Product pr:p.getProducts())
			em.merge(pr);
		em.merge(p);
		em.flush();
		return p;
	}

	@Override
	public boolean delete(int id) {
		DefaultPacket dp=findDefaultPacket(id);
		if( dp!=null ) {
			em.remove(dp);
			em.remove(dp.getPacket());
			return true;
		}
		CustomPacket cp=findCustomPacket(id);	
		if( cp!=null ) {
			em.remove(cp);
			em.remove(cp.getPacket());
			return true;
		}
		return false;
	}

	@Override
	public DefaultPacket findDefaultPacket(int id) {
		return em.find(DefaultPacket.class, id);
	}

	@Override
	public CustomPacket findCustomPacket(int id) {
		return em.find(CustomPacket.class, id);
	}
	
}
